// entry/src/main/ets/services/PushTokenService.ts

import { pushService } from '@kit.PushKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { UIAbility } from '@kit.AbilityKit';

const DOMAIN = 0x0001;
const TAG = 'PushTokenService';

/**
 * Push Token 服务类
 * 负责获取、删除和管理设备的 Push Token
 */
class PushTokenService {
  private pushToken: string = '';
  private ability?: UIAbility;

  /**
   * 获取 Push Token
   * @returns Push Token 字符串，失败返回空字符串
   */
  async getToken(): Promise<string> {
    try {
      hilog.info(DOMAIN, TAG, '正在获取 Push Token...');
      this.pushToken = await pushService.getToken();
      hilog.info(DOMAIN, TAG, `✅ 成功获取 Push Token: ${this.pushToken}`);

      // 格式化输出 Push Token（类似示例格式）
      const formattedToken = this.formatToken(this.pushToken);
      hilog.info(DOMAIN, TAG, `格式化 Token: ${formattedToken}`);

      return this.pushToken;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(DOMAIN, TAG, `❌ 获取 Push Token 失败: code=${error.code}, message=${error.message}`);

      // 处理常见错误
      this.handleTokenError(error);

      return '';
    }
  }

  /**
   * 删除 Push Token
   * @returns 是否成功删除
   */
  async deleteToken(): Promise<boolean> {
    try {
      hilog.info(DOMAIN, TAG, '正在删除 Push Token...');
      await pushService.deleteToken();
      this.pushToken = '';
      hilog.info(DOMAIN, TAG, '✅ 成功删除 Push Token');
      return true;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(DOMAIN, TAG, `❌ 删除 Push Token 失败: code=${error.code}, message=${error.message}`);
      return false;
    }
  }

  /**
   * 获取已缓存的 Push Token（不重新请求）
   */
  getCachedToken(): string {
    return this.pushToken;
  }

  /**
   * 设置 Ability 实例（用于 Token 更新监听）
   * @param ability UIAbility 实例
   */
  setAbility(ability: UIAbility): void {
    this.ability = ability;
  }

  /**
   * 监听 Token 更新事件
   * 当 Token 发生变化时（如设备迁移到其他国家/地区），会触发此回调
   * 注意：必须先调用 setAbility() 设置 Ability 实例
   */
  onTokenUpdate(callback: (token: string) => void): void {
    if (!this.ability) {
      hilog.error(DOMAIN, TAG, '❌ 监听失败：Ability 实例未设置，请先调用 setAbility()');
      return;
    }

    try {
      // pushService.on 签名：on(type: "tokenUpdate", ability: Ability, callback: Callback<string>)
      pushService.on('tokenUpdate', this.ability, (data: string) => {
        hilog.info(DOMAIN, TAG, `🔄 Push Token 已更新: ${data}`);
        this.pushToken = data;
        callback(data);
      });
      hilog.info(DOMAIN, TAG, '✅ Token 更新监听已启动');
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(DOMAIN, TAG, `❌ 监听 Token 更新失败: ${error.code} ${error.message}`);
    }
  }

  /**
   * 取消监听 Token 更新事件
   */
  offTokenUpdate(): void {
    try {
      pushService.off('tokenUpdate');
      hilog.info(DOMAIN, TAG, '✅ Token 更新监听已取消');
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(DOMAIN, TAG, `❌ 取消监听失败: ${error.code} ${error.message}`);
    }
  }

  /**
   * 格式化 Push Token 输出（模拟示例格式）
   * 格式：IQAAAAC*************************dRH7_bPbfMrVfsYw
   */
  private formatToken(token: string): string {
    if (!token || token.length < 20) {
      return token;
    }

    // 显示前7位和后20位，中间用星号代替
    const prefix = token.substring(0, 7);
    const suffix = token.substring(token.length - 20);
    const maskedLength = token.length - 27;
    const masked = '*'.repeat(Math.max(maskedLength, 25));

    return `${prefix}${masked}${suffix}`;
  }

  /**
   * 处理 Token 获取错误
   */
  private handleTokenError(error: BusinessError): void {
    switch (error.code) {
      case 1000900010:
        hilog.error(DOMAIN, TAG, '⚠️ APP 身份验证失败，请检查：');
        hilog.error(DOMAIN, TAG, '  1. 是否在 AppGallery Connect 开通推送服务');
        hilog.error(DOMAIN, TAG, '  2. bundleName 是否与 AGC 配置一致');
        hilog.error(DOMAIN, TAG, '  3. 签名证书是否正确');
        hilog.error(DOMAIN, TAG, '  4. agconnect-services.json 是否配置正确');
        break;
      case 1000900004:
        hilog.error(DOMAIN, TAG, '⚠️ Push Kit 服务未连接，请检查设备网络');
        break;
      case 1000900003:
        hilog.error(DOMAIN, TAG, '⚠️ 频繁申请 Token，请稍后再试');
        break;
      default:
        hilog.error(DOMAIN, TAG, `⚠️ 未知错误: ${error.code}`);
    }
  }

  /**
   * 上报 Push Token 到应用服务器
   * @param token Push Token
   * @param username 用户名（可选）
   */
  async uploadTokenToServer(token: string, username?: string): Promise<boolean> {
    // TODO: 实现上报到后端服务器的逻辑
    // 格式建议：token + "," + username
    hilog.info(DOMAIN, TAG, `准备上报 Token 到服务器: ${this.formatToken(token)}`);

    if (username) {
      hilog.info(DOMAIN, TAG, `用户名: ${username}`);
    }

    // 示例：调用后端 API
    // try {
    //   const httpRequest = http.createHttp();
    //   const response = await httpRequest.request(
    //     `${AppConfig.API_BASE_URL}/api/push/register`,
    //     {
    //       method: http.RequestMethod.POST,
    //       header: {
    //         'Content-Type': 'application/json',
    //         'Authorization': `Token ${UserSessionManager.getToken()}`
    //       },
    //       extraData: JSON.stringify({
    //         token: token,
    //         username: username || ''
    //       })
    //     }
    //   );
    //   httpRequest.destroy();
    //   return response.responseCode === 200;
    // } catch (error) {
    //   return false;
    // }

    hilog.info(DOMAIN, TAG, '⚠️ 上报功能待实现（uploadTokenToServer）');
    return true;
  }
}

// 导出单例
export const pushTokenService = new PushTokenService();
